package org.light.simpleauth;

import java.util.ArrayList;
import java.util.List;

import org.light.core.Writeable;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.generator.Generator;
import org.light.utils.WriteableUtil;

public class ErrorGenerator extends Generator{
	public ErrorGenerator(){
		super();
		super.fileName = "error.rs";
		super.standardName = "Error";
	}

	@Override
	public StatementList generateStatementList() {
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,0,"use axum::{http::StatusCode,"));
		sList.add(new Statement(2000L,1,"response::{Redirect},"));
		sList.add(new Statement(3000L,1,"Json};"));
		sList.add(new Statement(4000L,0,"use serde_json::{json, Value};"));
		sList.add(new Statement(5000L,0,"use thiserror::Error;"));
		sList.add(new Statement(6000L,0,""));
		sList.add(new Statement(7000L,0,"#[derive(Debug, Error)]"));
		sList.add(new Statement(8000L,0,"pub enum Error {"));
		sList.add(new Statement(9000L,1,"#[error(transparent)]"));
		sList.add(new Statement(10000L,1,"SqlxError(#[from] sqlx::Error),"));
		sList.add(new Statement(11000L,1,"#[error(transparent)]"));
		sList.add(new Statement(12000L,1,"JwtError(#[from] jsonwebtoken::errors::Error),"));
		sList.add(new Statement(13000L,1,"#[error(transparent)]"));
		sList.add(new Statement(14000L,1,"TokioRecvError(#[from] tokio::sync::oneshot::error::RecvError),"));
		sList.add(new Statement(15000L,1,"#[error(transparent)]"));
		sList.add(new Statement(16000L,1,"AxumTypedHeaderError(#[from] axum::extract::rejection::TypedHeaderRejection),"));
		sList.add(new Statement(17000L,1,"#[error(transparent)]"));
		sList.add(new Statement(18000L,1,"AxumExtensionError(#[from] axum::extract::rejection::ExtensionRejection),"));
		sList.add(new Statement(19000L,1,"#[error(transparent)]"));
		sList.add(new Statement(20000L,1,"ValidationError(#[from] validator::ValidationErrors),"));
		sList.add(new Statement(21000L,1,"#[error(\"wrong credentials\")]"));
		sList.add(new Statement(22000L,1,"WrongCredentials,"));
		sList.add(new Statement(23000L,1,"#[error(\"password doesn't match\")]"));
		sList.add(new Statement(24000L,1,"WrongPassword,"));
		sList.add(new Statement(25000L,1,"#[error(\"email is already taken\")]"));
		sList.add(new Statement(26000L,1,"DuplicateUserEmail,"));
		sList.add(new Statement(27000L,1,"#[error(\"name is already taken\")]"));
		sList.add(new Statement(28000L,1,"DuplicateUserName,"));
		sList.add(new Statement(29000L,0,"}"));
		sList.add(new Statement(30000L,0,"pub type Result<T> = std::result::Result<T, Error>;"));
		sList.add(new Statement(31000L,0,""));
		sList.add(new Statement(32000L,0,"pub type ApiError = (StatusCode, Json<Value>);"));
		sList.add(new Statement(33000L,0,"pub type ApiResult<T> = std::result::Result<T, ApiError>;"));
		sList.add(new Statement(34000L,0,""));
		sList.add(new Statement(35000L,0,"impl From<Error> for ApiError {"));
		sList.add(new Statement(36000L,1,"fn from(err: Error) -> Self {"));
		sList.add(new Statement(37000L,2,"let status = match err {"));
		sList.add(new Statement(38000L,3,"Error::WrongCredentials => StatusCode::UNAUTHORIZED,"));
		sList.add(new Statement(39000L,3,"Error::ValidationError(_) => StatusCode::BAD_REQUEST,"));
		sList.add(new Statement(40000L,3,"_ => StatusCode::INTERNAL_SERVER_ERROR,"));
		sList.add(new Statement(41000L,2,"};"));
		sList.add(new Statement(42000L,2,"Redirect::permanent(\"/login/index.html\");"));
		sList.add(new Statement(43000L,2,"let payload = json!({\"message\": err.to_string()});"));
		sList.add(new Statement(44000L,2,"(status, Json(payload))"));
		sList.add(new Statement(45000L,1,"}"));
		sList.add(new Statement(46000L,0,"}"));

		return WriteableUtil.merge(sList);		
	}
}
